package com.zhss.demo.zookeeper;


import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.List;

/**
 * @author stone
 */
public class ClientBaseApi {

    static ZooKeeper zooKeeper;

    static volatile boolean connected = false;

    final static String rootPath = "/stone";

    static {
        try {
            zooKeeper = new ZooKeeper("127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186,127.0.0.1:2187", 10000,
                    (WatchedEvent event) -> {
                        if (Watcher.Event.KeeperState.SyncConnected == event.getState()) {
                            connected = true;
                        }
                        System.out.println("default watch... " + event);
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        while (!connected) {
            Thread.sleep(10);
        }
        clear();
        create();
        show();
//        getWatch();
        existsWatch();
        zooKeeper.close();
    }

    private static void create() throws Exception {
        clear();
        zooKeeper.create(rootPath, "root".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("创建根节点...");

        zooKeeper.create(rootPath + "/children", "child".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        zooKeeper.create(rootPath + "/children", "child".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        zooKeeper.create(rootPath + "/children", "child".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
        System.out.println("创建顺序子节点...");

        zooKeeper.create(rootPath + "/children", "child".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        System.out.println("创建临时节点...");

        zooKeeper.create(rootPath + "/childrenE", "childE".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        zooKeeper.create(rootPath + "/childrenE", "childE".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        zooKeeper.create(rootPath + "/childrenE", "childE".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println("创建临时节点顺序...");
        byte[] data = zooKeeper.getData(rootPath, false, new Stat());
        System.out.println(new String(data));
    }

    private static void show() throws Exception {
        Stat stat = zooKeeper.exists(rootPath, false);
        if (stat == null) {
            return;
        }
        byte[] data = zooKeeper.getData(rootPath, false, new Stat());
        System.out.println(rootPath + ":" + new String(data));
        List<String> children = zooKeeper.getChildren(rootPath, false);
        for (String childPath : children) {
            childPath = rootPath + "/" + childPath;
            byte[] childData = zooKeeper.getData(childPath, false, new Stat());
            System.out.println(childPath + ":" + new String(childData));
        }
    }

    private static void clear() throws Exception {

        Stat stat = zooKeeper.exists(rootPath, false);
        if (stat == null) {
            return;
        }
        List<String> children = zooKeeper.getChildren(rootPath, false);
        for (String childPath : children) {
            childPath = rootPath + "/" + childPath;
            zooKeeper.delete(childPath, -1);
        }
        zooKeeper.delete(rootPath, -1);
    }


    private static void getWatch() throws Exception {
        // /test 注册默认监听
        zooKeeper.create(rootPath + "/test", "test".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zooKeeper.getData(rootPath + "/test", true, new Stat());

        // 根节点注册监听
        zooKeeper.getData(rootPath, (WatchedEvent event) -> System.out.println("root data changed..." + event), new Stat());
        // 子节点注册监听
        zooKeeper.getChildren(rootPath, (WatchedEvent event) -> System.out.println("children data changed..." + event), new Stat());
        while (true) {
            Thread.sleep(1000);
        }
    }

    private static void existsWatch() throws Exception {

        // /test节点 注册默认监听
        zooKeeper.exists(rootPath + "/test", true);

        // /exists节点 注册监听
        zooKeeper.exists(rootPath + "/exists", new ExistsWatcher(zooKeeper));

        while (true) {
            Thread.sleep(1000);
        }
    }

    private static class ExistsWatcher implements Watcher {
        ZooKeeper zooKeeper;

        public ExistsWatcher(ZooKeeper zooKeeper) {
            this.zooKeeper = zooKeeper;
        }

        @Override
        public void process(WatchedEvent event) {
            try {
                System.out.println("exists watch。。"+event);
                zooKeeper.exists(event.getPath(), this);
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
